import { Context } from 'koa';
import Router from 'koa-router';
import { authMiddleware } from '../middleware/auth';
import { RowDataPacket, ResultSetHeader } from 'mysql2';
import { ApiResponse } from '../types';
import fs from 'fs';
import path, { basename, dirname } from 'path';

// 🌍 引入全局注入
import './global';

// 注册的函数列表
const registeredFunctions: Map<string, any> = new Map();
const routeConfig: Map<string, any> = new Map();

// 🔖 存储公开方法的元数据
const publicMethods = new Set<string>();

// 🌍 自动服务前缀映射 - 支持文件夹结构自动映射
function getServicePrefix(serviceName: string, filePath?: string): string {
  // 如果提供了文件路径，从路径中提取服务名
  if (filePath) {
    // 从文件路径中提取服务目录名
    // 例如：src/services/config/index.ts -> config
    // 例如：src/services/auth/index.ts -> auth
    const servicesMatch = filePath.match(/services\/([^\/]+)/);
   
  }
  
  // 移除 "Service" 后缀，转换为小写
  const cleanName = serviceName.replace(/Service$/, '').toLowerCase();
  
  // 特殊映射规则（向后兼容）
  const specialMappings: Record<string, string> = {
    'auth': '/api/auth',
    'product': '/api/product',    // 与前端接口一致，使用单数形式
    'order': '/api/orders',
    'user': '/api/user', 
    'config': '/api/config',
    'system': '/api/system',
    'upload': '/api/upload',
    'map': '/api/amap/ip',        // 地图服务特殊路径
    'merchant': '/api/merchants',
    'address': '/api/user/addresses' // 地址是用户子模块
  };
   
  return specialMappings[cleanName] || `/api/${cleanName}`;
}

// 🔍 自动扫描services目录
function autoDiscoverServices() {
  const servicesDir = path.join(__dirname, '../services');
  
  if (!fs.existsSync(servicesDir)) {
    console.log('⚠️  Services目录不存在，跳过自动扫描');
    return;
  }
  
  console.log('🔍 开始自动扫描services目录...');
  
  function scanDirectory(dirPath: string) {
    const items = fs.readdirSync(dirPath);
    
    for (const item of items) {
      const fullPath = path.join(dirPath, item);
      const stat = fs.statSync(fullPath);
      
      if (stat.isDirectory()) {
        // 检查是否有index.ts文件
        const indexPath = path.join(fullPath, 'index.ts');
        if (fs.existsSync(indexPath)) {
          console.log(`📁 发现服务模块: ${item} -> ${indexPath}`);
          try {
            // 动态导入服务模块
            require(indexPath);
          } catch (error: any) {
            console.log(`❌ 导入服务失败 ${item}:`, error.message);
          }
        }
        // 递归扫描子目录
        scanDirectory(fullPath);
      } else if (item.endsWith('.ts') && item !== 'index.ts') {
        // 扫描独立的服务文件
        try {
          console.log(`📄 发现服务文件: ${item} -> ${fullPath}`);
          require(fullPath);
        } catch (error: any) {
          console.log(`❌ 导入服务失败 ${item}:`, error.message);
        }
      }
    }
  }
  
  scanDirectory(servicesDir);
  console.log('✅ 服务扫描完成\n');
}

// 数据库操作函数
export async function query(sql: string, params: any[] = []): Promise<any[]> {
  const { pool } = await import('../config/database');
  const [results] = await pool.query(sql, params);
  return results as any[];
}

export async function queryOne<T = any>(sql: string, params: any[] = []): Promise<T | null> {
  const results = await query(sql, params);
  return results.length > 0 ? results[0] as T : null;
}

export async function insert(sql: string, params: any[] = []): Promise<any> {
  const { pool } = await import('../config/database');
  const [result] = await pool.execute(sql, params);
  return result;
}

export async function execute(sql: string, params: any[] = []): Promise<any> {
  const { pool } = await import('../config/database');
  const [result] = await pool.execute(sql, params);
  return result;
}

// AutoService 基类
export class AutoService {
  [key: string]: any; // 添加索引签名

  constructor() {
    this.registerMethods();
  }

  private registerMethods() {
    const serviceName = this.constructor.name;
    const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(this));
    
    console.log(`🔍 发现服务: ${serviceName}`);
    
    // 🗂️ 尝试从调用栈获取文件路径
    const stack = new Error().stack;
    let filePath = '';
    if (stack) {
      const stackLines = stack.split('\n');
      for (const line of stackLines) {
        if (line.includes('services/') && line.includes('.ts')) {
          const match = line.match(/\((.+\.ts):\d+:\d+\)/);
          if (match) {
            filePath = match[1];
            break;
          }
        }
      }
    }
    
    methods.forEach(methodName => {
      if (methodName !== 'constructor' && typeof (this as any)[methodName] === 'function' && !methodName.startsWith('_')) {
        const functionKey = `${serviceName}.${methodName}`;
        registeredFunctions.set(functionKey, (this as any)[methodName].bind(this));
        
        // 检查是否是公开方法
        const requireAuth = !publicMethods.has(functionKey);
        
        // 存储路由配置，包含文件路径信息
        routeConfig.set(functionKey, {
          serviceName,
          methodName,
          filePath,
          requireAuth
        });
        
        console.log(`  📋 注册方法: ${methodName} ${requireAuth ? '🔒' : '🌍'}`);
      }
    });
  }
}

// 装饰器（简化版，主要用于标记无需认证的路由）
export function Public(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  const serviceName = target.constructor.name;
  const functionKey = `${serviceName}.${propertyKey}`;
  
  // 直接标记为公开方法
  publicMethods.add(functionKey);
  console.log(`🌍 标记公开方法: ${functionKey}`);
}

// 注册函数
export function registerFunction(name: string, func: Function, config: any = {}) {
  registeredFunctions.set(name, func);
  routeConfig.set(name, { requireAuth: true, ...config });
}

// 生成路由的函数
export function generateRoutes(defaultPrefix: string = '/api'): Router {
  const router = new Router();
  
  console.log(`\n🚀 开始自动生成路由...`);
  
  registeredFunctions.forEach((func, functionKey) => {
    const config = routeConfig.get(functionKey) || {};
    const [serviceName, methodName] = functionKey.split('.');
    
    // 🎯 自动确定路由前缀（优先使用文件路径）
    const prefix = getServicePrefix(serviceName, config.filePath);
    
    // 根据方法名确定HTTP方法和路径
    const { method, path } = parseMethodName(methodName, prefix);
    
    // 创建中间件数组
    const middlewares = [];
    if (config.requireAuth) {
      middlewares.push(authMiddleware);
    }
    
    // 添加主处理函数
    middlewares.push(async (ctx: any) => {
      try {
        const userId = ctx.state.user?.id || null;
        const { id, data, ...query } = { ...ctx.params, ...ctx.query, ...ctx.request.body };
        
        let result;
        
        // 🎯 智能参数匹配
        if (id !== undefined && data !== undefined) {
          result = await func(userId, id, data);
        } else if (id !== undefined) {
          result = await func(userId, id, query);
        } else if (Object.keys(ctx.request.body || {}).length > 0) {
          result = await func(userId, ctx.request.body);
        } else {
          result = await func(userId, query);
        }
        
        // 统一响应格式
        if (result && typeof result === 'object' && 'code' in result) {
          ctx.status = result.code;
          ctx.body = {
            success: result.code >= 200 && result.code < 300,
            message: result.message,
            data: result.data
          };
        } else {
          ctx.body = {
            success: true,
            data: result,
            message: 'success'
          };
        }
      } catch (error: any) {
        console.error(`❌ 路由错误 ${method} ${path}:`, error.message);
        
        if (error && typeof error === 'object' && 'code' in error) {
          ctx.status = error.code;
          ctx.body = {
            success: false,
            message: error.message,
            data: error.data
          };
        } else {
          ctx.status = 500;
          ctx.body = {
            success: false,
            message: error?.message || '服务器内部错误',
            data: null
          };
        }
      }
    });
    
    // 注册路由
    (router as any)[method.toLowerCase()](path, ...middlewares);
    console.log(`✅ ${method.padEnd(6)} ${path} ${config.requireAuth ? '🔒' : '🌍'} ${config.filePath ? `📁 ${basename(dirname(config.filePath))}` : ''}`);
  });
  
  console.log(`\n🎉 自动路由生成完成！共注册 ${registeredFunctions.size} 个路由\n`);
  
  return router;
}

// 🔄 自动初始化函数
export function initAutoRoutes(): Router {
  console.log('🚀 启动自动路由系统...\n');
  
  // 直接生成路由，不做自动扫描
  return generateRoutes();
}

// 智能解析方法名为HTTP方法和路径
function parseMethodName(methodName: string, prefix: string): { method: string; path: string } {
  // 🧠 智能清理方法名
  let cleanMethodName = methodName;
  
  // 移除服务前缀（如 getAuthMe → getMe, createAuthLogin → createLogin）
  const servicePrefixes = ['Auth', 'Product', 'Order', 'User', 'Config', 'System', 'Upload', 'Map', 'Merchant', 'Address'];
  for (const servicePrefix of servicePrefixes) {
    if (methodName.includes(servicePrefix) && !methodName.startsWith('create' + servicePrefix)) {
      cleanMethodName = methodName.replace(new RegExp(servicePrefix, 'g'), '');
      break;
    }
  }
  
  // 🎯 智能HTTP方法检测
  let method = 'GET';
  let pathSuffix = '';
  
  if (cleanMethodName.startsWith('create')) {
    method = 'POST';
    pathSuffix = cleanMethodName.replace('create', '').toLowerCase();
  } else if (cleanMethodName.startsWith('update')) {
    method = 'PUT';
    pathSuffix = cleanMethodName.replace('update', '').toLowerCase();
    if (pathSuffix && pathSuffix !== 'id') {
      pathSuffix = pathSuffix === 'id' ? '' : `/:id/${pathSuffix}`;
    } else {
      pathSuffix = '/:id';
    }
  } else if (cleanMethodName.startsWith('delete')) {
    method = 'DELETE';
    pathSuffix = cleanMethodName.replace('delete', '').toLowerCase();
    pathSuffix = pathSuffix && pathSuffix !== 'id' ? `/:id/${pathSuffix}` : '/:id';
  } else if (cleanMethodName.startsWith('get')) {
    method = 'GET';
    pathSuffix = cleanMethodName.replace('get', '').toLowerCase();
    
    // 🧠 智能路径处理
    if (pathSuffix === 'id' || pathSuffix === '' || pathSuffix === 'detail') {
      pathSuffix = '/:id';
    } else if (pathSuffix.includes('id')) {
      pathSuffix = pathSuffix.replace('id', '/:id');
    }
  }
  
  // 🔨 构建完整路径
  let fullPath = prefix;
  if (pathSuffix && pathSuffix !== '') {
    if (!pathSuffix.startsWith('/')) {
      pathSuffix = '/' + pathSuffix;
    }
    fullPath += pathSuffix;
  }
  
  // 🧹 路径清理
  if (fullPath.endsWith('/') && fullPath.length > 1) {
    fullPath = fullPath.slice(0, -1);
  }
  
  return { method, path: fullPath };
}